home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_11 / phillip2 / morph.c < prev    next >
C/C++ Source or Header  |  1993-05-15  |  60KB  |  2,212 lines

  1.  
  2.    /*************************** 
  3.    * 
  4.    *   morph.c 
  5.    *   COMPOSITE FILE COMPRISING: 
  6.    *   ed.c 
  7.    *   skeleton.c 
  8.    * 
  9.    *************************** 
  10.  
  11.  
  12.  
  13.        /**********************************************
  14.        *
  15.        *   file d:\cips\ed.c
  16.        *
  17.        *   Functions: This file contains
  18.        *      erosion
  19.        *      dilation
  20.        *      mask_erosion
  21.        *      mask_dilation
  22.        *      interior_outline
  23.        *      exterior_outline
  24.        *      copy_3_x_3
  25.        *      opening
  26.        *      closing
  27.        *      get_shape_options
  28.        *
  29.        *   Purpose:
  30.        *      These functions perform the erosion,
  31.        *      dilation, outlining, opening and
  32.        *      closing operations.
  33.        *
  34.        *   External Calls:
  35.        *      wtiff.c - round_off_image_size
  36.        *                create_file_if_needed
  37.        *                write_array_into_tiff_image
  38.        *      tiff.c - read_tiff_header
  39.        *      rtiff.c - read_tiff_image
  40.        *      numcvrt.c - get_integer
  41.        *
  42.        *   Modifications:
  43.        *      14 March 1993 - created
  44.        *
  45.        ************************************************/
  46.  
  47. #include "cips.h"
  48.  
  49.  
  50.  
  51. short edmask1[3][3] = {{0, 1, 0},
  52.                        {0, 1, 0},
  53.                        {0, 1, 0}};
  54.  
  55. short edmask2[3][3] = {{0, 0, 0},
  56.                        {1, 1, 1},
  57.                        {0, 0, 0}};
  58.  
  59. short edmask3[3][3] = {{0, 1, 0},
  60.                        {1, 1, 1},
  61.                        {0, 1, 0}};
  62.  
  63. short edmask4[3][3] = {{1, 1, 1},
  64.                        {1, 1, 1},
  65.                        {1, 1, 1}};
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.      /*******************************************
  73.      *
  74.      *   mask_dilation(...
  75.      *
  76.      *   This function performs the dilation
  77.      *   operation using the erosion-dilation
  78.      *   3x3 masks given above.  It works on
  79.      *   0-value images.
  80.      *
  81.      *******************************************/
  82.  
  83. mask_dilation(in_name, out_name, the_image, out_image,
  84.               il, ie, ll, le, value, mask_type)
  85.    char   in_name[], out_name[];
  86.    int    il, ie, ll, le;
  87.    short  the_image[ROWS][COLS],
  88.           out_image[ROWS][COLS],
  89.           mask_type, value;
  90. {
  91.    int    a, b, count, i, j, k;
  92.    short  mask[3][3], max;
  93.  
  94.       /**************************************
  95.       *
  96.       *   Copy the 3x3 erosion-dilation mask
  97.       *   specified by the mask_type.
  98.       *
  99.       ***************************************/
  100.  
  101.    switch(mask_type){
  102.       case 1:
  103.          copy_3_x_3(mask, edmask1);
  104.          break;
  105.       case 2:
  106.          copy_3_x_3(mask, edmask2);
  107.          break;
  108.       case 3:
  109.          copy_3_x_3(mask, edmask3);
  110.          break;
  111.       case 4:
  112.          copy_3_x_3(mask, edmask4);
  113.          break;
  114.       default:
  115.          printf("\nInvalid mask type, using mask 4");
  116.          copy_3_x_3(mask, edmask4);
  117.          break;
  118.    }
  119.  
  120.    create_file_if_needed(in_name, out_name, out_image);
  121.  
  122.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  123.  
  124.       /***************************
  125.       *
  126.       *   Loop over image array
  127.       *
  128.       ****************************/
  129.  
  130.    printf("\n");
  131.  
  132.    for(i=1; i<ROWS-1; i++){
  133.       if( (i%10) == 0) printf("%3d", i);
  134.       for(j=1; j<COLS-1; j++){
  135.          max = 0;
  136.          for(a=-1; a<=1; a++){
  137.              for(b=-1; b<=1; b++){
  138.                 if(mask[a+1][b+1] == 1){
  139.                    if(the_image[i+a][j+b] > max)
  140.                       max = the_image[i+a][j+b];
  141.                 }  /* ends if mask == 1 */
  142.              }  /*  ends loop over b */
  143.          }  /* ends loop over a */
  144.          out_image[i][j] = max;
  145.       }  /* ends loop over j */
  146.    }  /* ends loop over i */
  147.  
  148.    fix_edges(out_image, 3);
  149.  
  150.    write_array_into_tiff_image(out_name, out_image,
  151.                                il, ie, ll, le);
  152.  
  153. }  /* ends mask_dilation */
  154.  
  155.  
  156.  
  157.  
  158.  
  159.      /*******************************************
  160.      *
  161.      *   mask_erosion(...
  162.      *
  163.      *   This function performs the erosion
  164.      *   operation using the erosion-dilation
  165.      *   3x3 masks given above.  It works on
  166.      *   0-value images.
  167.      *
  168.      *******************************************/
  169.  
  170. mask_erosion(in_name, out_name, the_image, out_image,
  171.              il, ie, ll, le, value, mask_type)
  172.    char   in_name[], out_name[];
  173.    int    il, ie, ll, le;
  174.    short  the_image[ROWS][COLS],
  175.           out_image[ROWS][COLS],
  176.           mask_type, value;
  177. {
  178.    int    a, b, count, i, j, k;
  179.    short  mask[3][3], min;
  180.  
  181.       /**************************************
  182.       *
  183.       *   Copy the 3x3 erosion-dilation mask
  184.       *   specified by the mask_type.
  185.       *
  186.       ***************************************/
  187.  
  188.    switch(mask_type){
  189.       case 1:
  190.          copy_3_x_3(mask, edmask1);
  191.          break;
  192.       case 2:
  193.          copy_3_x_3(mask, edmask2);
  194.          break;
  195.       case 3:
  196.          copy_3_x_3(mask, edmask3);
  197.          break;
  198.       case 4:
  199.          copy_3_x_3(mask, edmask4);
  200.          break;
  201.       default:
  202.          printf("\nInvalid mask type, using mask 4");
  203.          copy_3_x_3(mask, edmask4);
  204.          break;
  205.    }
  206.  
  207.    create_file_if_needed(in_name, out_name, out_image);
  208.  
  209.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  210.  
  211.       /***************************
  212.       *
  213.       *   Loop over image array
  214.       *
  215.       ****************************/
  216.  
  217.    printf("\n");
  218.  
  219.    for(i=1; i<ROWS-1; i++){
  220.       if( (i%10) == 0) printf("%3d", i);
  221.       for(j=1; j<COLS-1; j++){
  222.          min = value;
  223.          for(a=-1; a<=1; a++){
  224.              for(b=-1; b<=1; b++){
  225.                 if(mask[a+1][b+1] == 1){
  226.                    if(the_image[i+a][j+b] < min)
  227.                       min = the_image[i+a][j+b];
  228.                 }  /* ends if mask == 1 */
  229.              }  /*  ends loop over b */
  230.          }  /* ends loop over a */
  231.          out_image[i][j] = min;
  232.       }  /* ends loop over j */
  233.    }  /* ends loop over i */
  234.  
  235.    fix_edges(out_image, 3);
  236.  
  237.    write_array_into_tiff_image(out_name, out_image,
  238.                                il, ie, ll, le);
  239.  
  240. }  /* ends mask_erosion */
  241.  
  242.  
  243.  
  244.  
  245.  
  246.      /*******************************************
  247.      *
  248.      *   erosion(...
  249.      *
  250.      *   This function performs the erosion
  251.      *   operation.  If a value pixel has more
  252.      *   than the threshold number of 0
  253.      *   neighbors, you erode it by setting it
  254.      *   to 0.
  255.      *
  256.      *******************************************/
  257.  
  258. erosion(in_name, out_name, the_image, out_image,
  259.         il, ie, ll, le, value, threshold)
  260.    char   in_name[], out_name[];
  261.    int    il, ie, ll, le;
  262.    short  the_image[ROWS][COLS],
  263.           out_image[ROWS][COLS],
  264.           threshold, value;
  265. {
  266.    int    a, b, count, i, j, k;
  267.  
  268.    create_file_if_needed(in_name, out_name, out_image);
  269.  
  270.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  271.  
  272.       /***************************
  273.       *
  274.       *   Loop over image array
  275.       *
  276.       ****************************/
  277.  
  278.    for(i=0; i<ROWS; i++)
  279.       for(j=0; j<COLS; j++)
  280.          out_image[i][j] = the_image[i][j];
  281.  
  282.    printf("\n");
  283.  
  284.    for(i=1; i<ROWS-1; i++){
  285.       if( (i%10) == 0) printf("%3d", i);
  286.       for(j=1; j<COLS-1; j++){
  287.          if(the_image[i][j] == value){
  288.             count = 0;
  289.             for(a=-1; a<=1; a++){
  290.                 for(b=-1; b<=1; b++){
  291.                       if(the_image[i+a][j+b] == 0)
  292.                          count++;
  293.                 }  /*  ends loop over b */
  294.             }  /* ends loop over a */
  295.             if(count > threshold) out_image[i][j] = 0;
  296.          }  /* ends if the_image == value */
  297.       }  /* ends loop over j */
  298.    }  /* ends loop over i */
  299.  
  300.    fix_edges(out_image, 3);
  301.  
  302.    write_array_into_tiff_image(out_name, out_image,
  303.                                il, ie, ll, le);
  304.  
  305. }  /* ends erosion */
  306.  
  307.  
  308.  
  309.  
  310.  
  311.      /*******************************************
  312.      *
  313.      *   dilation(...
  314.      *
  315.      *   This function performs the dilation
  316.      *   operation.  If a 0 pixel has more than
  317.      *   threshold number of value n